var _inherit = require('core/inherit.js');
var _vec3f = require('core/glm.js').vec3f;

var _Target = require('./targetaction.js');
var S = require('res/style.js');
var style = S.game.cells.bonus;
var maxstyle = S.game.cells.bonus;

var _Utility = require('scenes/utility.js');
var _getBonus = require('scenes/utility.js').getBonus;
var TWEEN = require('./tweens.js');
var _Constant = require('./constant.js');

var POPUP_DELAY = 0.20;

// ==========================
// DiscountTween
// ==========================
/**
 * @param cells discount slots
 * @constructor
 */
function DiscountTween(cells) {
    this.mCells = cells;
    this.degree = 0;
}
DiscountTween.prototype.onStart = function () {
    for (var i = 0, l = this.mCells.length; i < l; i++) {
        this.mCells[i].setDisable(true);
        this.mCells[i].startFlip();
    }
};
DiscountTween.prototype.onComplete = function () {
    for (var i = 0, l = this.mCells.length; i < l; i++) {
        this.mCells[i].endFlip(true);
    }
};
DiscountTween.prototype.update = function () {
    for (var i = 0, l = this.mCells.length; i < l; i++) {
        this.mCells[i].setFlip(this.degree);
    }
};
DiscountTween.prototype.startAnima = function () {
    return new TWEEN.Tween(this)
        .to({degree: 180}, 0.18)
        .onUpdate(this.update)
        .onComplete(this.onComplete);
};

// ==========================
// CellTween
// ==========================
var SPEED_PARAM = 1.5;
/**
 * flip and popup bonus score
 * @param cell
 * @param layer
 * @constructor
 */
function CellTween(container, cell, layer, ismax) {
    this.mContainer = container

    this.mInitSpeed = 120 * SPEED_PARAM;
    this.degree = 0;
    this.time = 0;
    this.speed = this.mInitSpeed;

    this.mBonus = _getBonus(cell.getCount());
    var text;
    if (!ismax) {
        text = style.createText('+' + _Utility.numberFormat(this.mBonus));
    } else {
        text = maxstyle.createText('+' + _Utility.numberFormat(this.mBonus));
    }
    text.setVisiable(false);
    text.setAnchor(0.5, 0.5);

    var maxwidth = _Constant.slotSize[1] - 2;
    var twidth = text.width();
    if (twidth > maxwidth) {
        text.setScale(maxwidth / twidth, maxwidth / twidth);
    }
    layer.addChild(text);

    this.mCell = cell;
    this.mPosition = new _vec3f(cell.getPosition());
    this.mScore = text;
    this.mScorePos = this.mScore.getPosition();
}
CellTween.prototype.getScore = function () {
    return this.mBonus;
};

CellTween.prototype.onFlipComplete = function () {
    this.mCell.endFlip(false);
};
CellTween.prototype.updateFlip = function () {
    this.mCell.setFlip(this.degree);
};
// ---------------- update
CellTween.prototype.updateStart = function () {
    this.mScore.setVisiable(true);
    this.mContainer.countScore(this.mBonus);
};
CellTween.prototype.updatePosition = function () {
    this.mScorePos.set(0, (this.mInitSpeed + this.speed) * 0.5 * this.time, 0);
    this.mScorePos.add(this.mPosition);
    this.mScore.touchMatrix();
};

CellTween.prototype.startPopupAndFlip = function (tweens, delay) {
    this.mCell.startFlip();

    var poptime = 120 / 180 / SPEED_PARAM;

    tweens.push(new TWEEN.Tween(this)
        .to({degree: 180}, 0.18)
        .delay(delay)
        .onUpdate(this.updateFlip)
        .onComplete(this.onFlipComplete));

    tweens.push(new TWEEN.Tween(this)
        .to({speed: 0, time: poptime}, poptime)
        .delay(delay)
        .onStart(this.updateStart)
        .onUpdate(this.updatePosition));
};

// ==========================
// ScoreCounting
// ==========================
function compair(slot1, slot2) {
    return slot1.getCell().getCount() - slot2.getCell().getCount();
}
/**
 * @param area game area
 * @constructor
 */
function PopupAnima(area) {
    _Target.onCreate(this);

    this.mTotalBonus = 0;
    this.mCounted = 0;
    this.initDiscount(area);
}
_Target.asAction(PopupAnima);
PopupAnima.prototype.appendCell = function (tweens, delay, cell, layer, ismax) {
    var cellAdapter = new CellTween(this, cell, layer, ismax);
    this.mTotalBonus += cellAdapter.getScore();
    cellAdapter.startPopupAndFlip(tweens, delay);
};
/**
 * flip card 1 & 2
 */
PopupAnima.prototype.initDiscount = function (area) {
    var slots = [].concat(area.getCellSlots());
    slots.sort(compair);

    var discount = [];
    var countcells = [];
    var celltweens = [];
    var tween;

    // animation layer
    var layer = area.getAnimaLayer();
    for (var i = 0, l = slots.length; i < l; i++) {
        var cell = slots[i].getCell();
        if (cell.getCount() < 3) {
            discount.push(cell);
        } else {
            countcells.push(cell);
        }
    }

    // discount 1 & 2
    var lasttween;
    if (discount.length > 0) {
        lasttween = tween = new DiscountTween(discount).startAnima();
    }
    if (countcells.length > 0) {
        var max = countcells[countcells.length - 1].getCount();
        for (var i = 0; i < countcells.length; i++) {
            this.appendCell(celltweens, POPUP_DELAY * i, countcells[i], layer, countcells[i].getCount() == max);
        }
    }

    if (celltweens.length > 0) {
        var cellanima = new TWEEN.Tween({});
        cellanima.chain.apply(cellanima, celltweens);
        if (tween) {
            cellanima.to({}, 0.18);
            tween.chain(cellanima);
        } else {
            tween = cellanima;
        }
        lasttween = celltweens.pop();
    }

    var action = this;
    lasttween.onComplete(function () {
        action.fire('finish');
        action.off('finish');

        action.fire('scorechange', action.mTotalBonus);
        action.off('scorechange');
    })
    tween.start();
};
PopupAnima.prototype.countScore = function (score) {
    this.mCounted += score;
    this.fire('scorechange', this.mCounted);
};

module.exports = PopupAnima;